import pandas as pd
import joblib
import os


def get_result(new_data: pd.DataFrame):
    working_directory = 'all_model_results/Decisiontree'

    # 删除不必要的列（transaction_id 和 user_id）
    for col in ['transaction_id', 'user_id']:
        if col in new_data.columns:
            new_data.drop(columns=col, inplace=True)

    # 处理时间戳
    new_data['transaction_timestamp'] = pd.to_datetime(new_data['transaction_timestamp'], errors='coerce')
    new_data['hour'] = new_data['transaction_timestamp'].dt.hour
    new_data['dayofweek'] = new_data['transaction_timestamp'].dt.dayofweek
    new_data.drop(columns=['transaction_timestamp'], inplace=True)

    # 定义分类变量和数值变量（均为小写）
    categorical_columns = [
        'authentication_method', 'device_type', 'merchant_category',
        'transaction_type', 'location', 'card_type'
    ]
    numerical_columns = [
        'transaction_amount', 'account_balance', 'ip_address_flag',
        'previous_fraudulent_activity', 'daily_transaction_count',
        'avg_transaction_amount_7d', 'failed_transaction_count_7d',
        'card_age', 'transaction_distance', 'risk_score', 'is_weekend',
        'hour', 'dayofweek'
    ]

    # 删除目标变量（如果存在）
    if 'fraud_label' in new_data.columns:
        new_data.drop(columns=['fraud_label'], inplace=True)

    # 对分类变量进行编码
    for col in categorical_columns:
        print(col)
        encoder_path = os.path.join(working_directory, f'{col}_encoder.joblib')
        encoder = joblib.load(encoder_path)
        new_data[col] = new_data[col].astype(str)
        new_data[col] = encoder.transform(new_data[col])

    # 对数值变量进行标准化
    scaler_path = os.path.join(working_directory, 'scaler.joblib')
    scaler = joblib.load(scaler_path)
    new_data[numerical_columns] = scaler.transform(new_data[numerical_columns])



    # 加载模型
    model_path = os.path.join(working_directory, f'{os.path.basename(working_directory)}_model.joblib')
    decisiontree = joblib.load(model_path)

    # 预测
    new_pred = decisiontree.predict(new_data)
    new_prob = decisiontree.predict_proba(new_data)[:, 1]
    if new_pred==0:
        new_prob = 1-new_prob

    return new_pred, new_prob
